<?php
/**
 * 设计师后台页面
 */
namespace website\controllers;

use Yii;
use yii\db\Expression;
use yii\helpers\ArrayHelper;
use common\helpers\Util;
use common\helpers\Pager;
use common\helpers\Render;
use common\helpers\Checker;
use common\helpers\Uploader;
use common\server\sms\SmsCaptcha;
use common\server\recharge\RechargeServer;
use common\models\Category;
use common\models\User;
use common\models\UserJob;
use common\models\UserBond;
use common\models\UserCategory;
use common\models\UserUpload;
use common\models\UserEducation;
use common\models\UserCollection;
use common\models\Design;
use common\models\Recruit;
use common\models\Employment;
use common\models\EmploymentPause;
use common\models\EmploymentAppeal;
use common\models\EmploymentSalary;
use common\models\RecruitApplicant;

class DesignerController extends UserController {
    
    /**
     * 判断用户是否设计师
     * @param $action
     * @return bool
     * @throws \yii\base\ExitException
     * @throws \yii\web\BadRequestHttpException
     */
    public function beforeAction($action)
    {
        if(parent::beforeAction($action)) {
            if($this->user->role != User::RoleDesigner) {
                if($this->request->isPost) {
                    Yii::$app->getResponse()->data = $this->json('Invalid.Request', '请稍后重试');
                }
                else {
                    Yii::$app->getResponse()->data = $this->error('请稍后重试', 'welcome/index');
                }
                // 发送response数据到页面
                Yii::$app->getResponse()->send();
                // 结束application
                Yii::$app->end();
                return false;
            }
            return true;
        }
        return false;
    }
    
    /**
     * 设计师后台主页
     * @return mixed
     */
    public function actionIndex()
    {
        if( ! $this->user->information()) {
            return $this->error('请先完善个人信息', 'designer/information');
        }
        $params['designer_id'] = $this->user->id;
        $query = RecruitApplicant::filterConditions(RecruitApplicant::initCondition(['designer_id'], $params));
        $employments = $query->with('recruit')->orderBy('created_at desc, id desc')
            ->limit(10)->asArray()->all();
        return $this->render('index', [
            'user' => $this->user,
            'applicants' => $this->user->getRecruitApplicants(0, 6),
            'employments' => $employments,
        ]);
    }
    
    /**
     * 设计师注册页面
     * @return mixed
     */
    public function actionInformation()
    {
        $user = $this->user;
        // 参数异常，渲染错误页面
        if( ! $this->request->isPost) {
            $uploads = $user->getUploads(UserUpload::TypeDesign)->select('image')->asArray()->all();
            $designs = [];
            foreach($uploads as & $design) {
                $designs[] = Render::upload($design['image']);
            }
            return $this->render('information', [
                'user' => $user,
                'designs' => json_encode($designs),
                'models' => Category::selector($this->params['designModelCategories']),
                'categories' => Category::selector($this->params['designCategories']),
            ]);
        }
        if($user->information()) {
            $this->json('Already', '个人资料已填写，如需修改，请联系客服');
        }
        $params = $this->request->post();
        $checker = Checker::authentication(User::flyer('information'), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', $checker['message']);
        }
        if( ! SmsCaptcha::validate($params['captcha'], 'user-information')) {
            return $this->json('Invalid.Captcha', '验证码错误（Invalid Captcha）');
        }
        $user->loads($params);
        if ( ! $user->validate()) {
            // 参数异常，渲染错误页面
            return $this->json('Invalid.Param', $user->errors());
        }
        // 开始上传图片
        $configurate = require Yii::getAlias('@common/config/uploader.php');
        // 上传微信二维码
        $loader = (new Uploader($configurate['designer']))->upload('wechat_qrcode');
        if($loader['code'] == SuccessCode) {
            Util::trashUpload($user->wechat_qrcode);
            $user->wechat_qrcode = $loader['path'];
        }
        // 上传手持身份证正面照
        $loader = (new Uploader($configurate['designer']))->upload('face_photo');
        if($loader['code'] == SuccessCode) {
            Util::trashUpload($user->face_photo);
            $user->face_photo = $loader['path'];
        }
        if ($user->save()) {
            // 擅长类目、模型、风格保存
            foreach(['category_id' => UserCategory::TypeCategory, 'model' => UserCategory::TypeModel, 'style' => UserCategory::TypeStyle] as $key => $type) {
                $user->saveCategories(empty($params[$key]) ? [] : $params[$key], $type);
            }
            // 作品上传
            $user->saveUploads('design', UserUpload::TypeDesign);
            // 保存成功
            return $this->json(SuccessCode, '保存成功');
        }
        // 参数异常，渲染错误页面
        return $this->json('System.Error', '提交失败，请重试');
    }
    
    /**
     * 设计师简历管理
     * @return mixed
     */
    public function actionResume()
    {
        if( ! $this->user->information()) {
            return $this->error('请先完善个人信息', 'designer/information');
        }
        return $this->render('resume', [
            'user' => $this->user,
            'models' => Category::selector($this->params['designModelCategories']),
            'categories' => Category::selector($this->params['designCategories']),
        ]);
    }
    
    /**
     * 保存教育经历
     * @return mixed
     */
    public function actionEducationUpdate()
    {
        $params = $this->request->post();
        $checker = Checker::authentication(UserEducation::flyer(), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', '教育经历填写异常：'.$checker['message']);
        }
        /** @var $education UserEducation */
        if( ! $education = $this->user->education) {
            $education = new UserEducation();
            $education->user_id = $this->user->id;
        }
        $education->loads($params);
        if( ! $education->validate()) {
            return $this->json('教育经历填写异常：'.$education->errors());
        }
        if($education->save()) {
            return $this->json(SuccessCode, '教育经历保存成功');
        }
        return $this->json('System.Error', '教育经历保存失败，请稍后重试');
    }
    
    /**
     * 获取用户工作经验详情
     * @return mixed
     */
    public function actionJobDetail()
    {
        if( ! $job = UserJob::canEdit($this->request->post('id'), ['user_id' => $this->user->id])) {
            return $this->json('Invalid.Param', '请刷新页面重试');
        }
        return $this->json(['job' => $job]);
    }
    
    /**
     * 保存工作经历
     * @return mixed
     */
    public function actionJobUpdate()
    {
        $params = $this->request->post();
        $checker = Checker::authentication(UserJob::flyer(), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', '工作经历填写异常：'.$checker['message']);
        }
        if($params['job_id']) {
            if( ! $job = UserJob::canEdit($params['job_id'])) {
                return $this->json('Invalid.Param', '请刷新页面重试');
            }
            if($job->user_id !== $this->user->id) {
                return $this->json('Invalid.Identify', '请刷新页面重试');
            }
        }
        else {
            $job = new UserJob();
            $job->user_id = $this->user->id;
        }
        $job->loads($params);
        if( ! $job->validate()) {
            return $this->json('工作经历填写异常：'.$job->errors());
        }
        if($job->save()) {
            return $this->json(SuccessCode, '工作经历保存成功', ['job' => $job]);
        }
        return $this->json('System.Error', '工作经历保存失败，请稍后重试');
    }
    /**
     * 删除工作经历
     * @return mixed
     */
    public function actionJobDelete()
    {
        if( ! $job = UserJob::canEdit($this->request->post('id'), ['user_id' => $this->user->id])) {
            return $this->json('Invalid.Param', '请刷新页面重试');
        }
        if($job->delete()) {
            return $this->json(SuccessCode, '工作经历删除成功');
        }
        return $this->json('System.Error', '工作经历删除失败，请稍后重试');
    }

    /**
     * 我的钱包
     * @return mixed
     */
    public function actionWallet()
    {
        if( ! $this->user->information()) {
            return $this->error('请先完善个人资料', 'designer/information');
        }
        $salary = EmploymentSalary::find()
            ->where(['designer_id' => $this->user->id, 'status' => [EmploymentSalary::StatusInit, EmploymentSalary::StatusPaying]])
            ->sum('hires');
        return $this->render('wallet', [
            'user' => $this->user,
            'frozen' => bcmul($salary, 0.6, 0),
        ]);
    }
    
    /**
     * 我的保证金
     * @return mixed
     */
    public function actionBond()
    {
        if( ! $this->user->information()) {
            return $this->error('请先完善个人资料', 'designer/information');
        }
        return $this->render('bond');
    }
    
    /**
     * 缴纳保证金
     * @return mixed
     */
    public function actionBondRecharge()
    {
        if( ! $this->user->active()) {
            return $this->json('Wait.Verify', '完善个人信息后，请耐心等待账号审核');
        }
        if($this->user->bond()) {
            return $this->json('Bond.Recharged', '您无需重复缴纳保证金');
        }
        if($this->user->alipay_score > User::BondAlipayScoreLimit) {
            $this->user->setBond(User::BondStatusAlipay);
            return $this->json('您的芝麻信用分已满足免除保证金额度，不需要缴纳保证金');
        }
        $params = $this->request->post();
        $checker = Checker::authentication(UserBond::flyer(), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', $checker['message']);
        }
        $attributes = [
            'platform' => $params['platform'],
            'remark' => '支付保证金',
        ];
        if( ! ($recharge = UserBond::creator($attributes))) {
            return $this->json('System.Error', '发起支付失败，请稍后重试');
        }
        $params = [
            'order_number' => $recharge->order_number,
            'amount' => $recharge->amount,
        ];
        $service = new RechargeServer($recharge->platform);
        $response = $service->recharge($params);
        Yii::info('返回数据：'.json_encode($response));
        if($service->success()) {
            return $this->json(SuccessCode, '请尽快完成支付', [
                'order_number' => $recharge->order_number,
                'payment' => $response['payment'],
                'javascript' => $response['javascript'],
            ]);
        }
        return $this->json('System.Error', '发起支付失败，请稍后重试');
    }
    
    /**
     * 我的投递
     * @return mixed
     */
    public function actionRecruitApplicantList()
    {
        if( ! $this->request->isPost) {
            if( ! $this->user->information()) {
                return $this->error('请先完善个人资料', 'designer/information');
            }
            return $this->render('recruit-applicant-list', [
                'models' => Category::selector($this->params['designModelCategories']),
                'categories' => Category::selector($this->params['designCategories']),
            ]);
        }
        $params['designer_id'] = $this->user->id;
        $query = RecruitApplicant::filterConditions(RecruitApplicant::initCondition(['designer_id'], $params));
        $data['page'] = Pager::page(['page_count' => 20, 'total_count' => $query->count()]);
        $data['infos'] = $query->with('recruit')->orderBy('created_at desc, id desc')
            ->offset(Pager::offset())->limit(Pager::limit())->asArray()->all();
        return $this->json($data);
    }
    
    /**
     * 投递简历
     * @return mixed
     */
    public function actionRecruitApplicant()
    {
        
        if( ! ($recruit = Recruit::canEdit($this->request->post('id')))) {
            return $this->json('Invalid.Recruit', '无效的招聘信息');
        }
        if( ! $this->user->bond()) {
            return $this->json('Bond.Status.Error', '请先交纳保证金');
        }
        if($recruit->delivery()) {
            return $this->json(SuccessCode, '简历投递成功');
        }
        return $this->json('System.Error', '简历投递失败，请稍后重试');
    }
    
    /**
     * 撤销投递
     * @return json
     */
    public function actionRecruitApplicantRevoke()
    {
        if( ! ($applicant = RecruitApplicant::canEdit($this->request->post('id'), ['designer_id' => $this->user->id]))) {
            return $this->json('Invalid.Applicant', '无效的岗位投递');
        }
        if($applicant->revoke()) {
            return $this->json(SuccessCode, '撤销岗位投递申请成功');
        }
        return $this->json('System.Error', '撤销岗位投递申请失败，请稍后重试');
    }
    
    /**
     * 雇佣列表
     * @return mixed
     */
    public function actionEmploymentList()
    {
        if( ! $this->request->isPost) {
            if( ! $this->user->information()) {
                return $this->error('请先完善个人资料', 'designer/information');
            }
            return $this->render('employment-list', [
                'status' => $this->request->get('status'),
            ]);
        }
        $params['status'] = $this->request->get('status');
        $params['designer_id'] = $this->user->id;
        $query = Employment::filterConditions(Employment::initCondition(['designer_id', 'status'], $params));
        $data['page'] = Pager::page(['page_count' => 20, 'total_count' => $query->count()]);
        $date = date('Ymd');
        $data['infos'] = $query->with('employer')->orderBy(new Expression("finish > {$date} desc, finish asc"))->offset(Pager::offset())->limit(Pager::limit())->asArray()->all();
        $pause = EmploymentPause::find()->where(['status' => [EmploymentPause::StatusInit, EmploymentPause::StatusConfirm], 'employment_id' => ArrayHelper::getColumn($data['infos'], 'id')])->asArray()->all();
        $data['pause'] = ArrayHelper::index($pause, 'employment_id');
        $appeal = EmploymentAppeal::find()->where(['status' => [EmploymentPause::StatusInit, EmploymentPause::StatusConfirm], 'employment_id' => ArrayHelper::getColumn($data['infos'], 'id')])->asArray()->all();
        $data['appeal'] = ArrayHelper::index($appeal, 'employment_id');
        return $this->json($data);
    }
    /**
     * 确认暂停雇佣服务
     * @return mixed
     */
    public function actionEmploymentConfirm()
    {
        if( ! $employment = Employment::canEdit($this->request->post('id'), ['designer_id' => $this->user->id])) {
            return $this->json('Invalid.Employment', '无效的雇佣信息（Invalid Employment）');
        }
        if($employment->confirm()) {
            return $this->json(SuccessCode, '接受雇佣成功，等待雇主支付订单');
        }
        return $this->json('System.Error', '接受雇佣失败，请稍后重试');
    }
    /**
     * 确认暂停雇佣服务
     * @return mixed
     */
    public function actionEmploymentPause()
    {
        if( ! $employment = Employment::canEdit($this->request->post('id'), ['designer_id' => $this->user->id])) {
            return $this->json('Invalid.Employment', '无效的雇佣信息（Invalid Employment）');
        }
        if($employment->confirmPause()) {
            return $this->json(SuccessCode, '确认暂停成功，您的工作已顺延');
        }
        return $this->json('System.Error', '确认暂停失败，请稍后重试');
    }
    /**
     * 雇佣服务申诉
     * @return mixed
     */
    public function actionEmploymentAppeal()
    {
        $params = $this->request->post();
        $checker = Checker::authentication(EmploymentAppeal::flyer(), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', $checker['message']);
        }
        if( ! $employment = Employment::canEdit($params['employment_id'], ['designer_id' => $this->user->id])) {
            return $this->json('Invalid.Employment', '无效的雇佣信息（Invalid Employment）');
        }
        $params['handler'] = EmploymentAppeal::HandlerDesigner;
        if($employment->applyAppeal($params)) {
            return $this->json(SuccessCode, '申诉成功，请耐心等待');
        }
        return $this->json('System.Error', '申诉失败，请稍后重试');
    }
    
    /**
     * 收藏的招聘信息
     * @return mixed
     */
    public function actionCollectionRecruitList()
    {
        if( ! $this->request->isPost) {
            if( ! $this->user->information()) {
                return $this->error('请先完善个人资料', 'designer/information');
            }
            return $this->render('collection-recruit-list');
        }
        $params['user_id'] = $this->user->id;
        $params['type'] = UserCollection::TypeRecruit;
        $query = UserCollection::filterConditions(UserCollection::initCondition(['user_id', 'type'], $params));
        $data['page'] = Pager::page(['page_count' => 20, 'total_count' => $query->count()]);
        $data['infos'] = $query->with('recruit')->orderBy('created_at desc')->offset(Pager::offset())->limit(Pager::limit())->asArray()->all();
        return $this->json($data);
    }
    
    /**
     * 作品管理 - 我的作品
     * @return mixed
     */
    public function actionDesignList()
    {
        if( ! $this->request->isPost) {
            return $this->render('design-list');
        }
        $params['designer_id'] = $this->user->id;
        $query = Design::filterConditions(Design::initCondition(['designer_id'], $params));
        $data['page'] = Pager::page(['page_count' => 20, 'total_count' => $query->count()]);
        $data['infos'] = $query->with('designer')->offset(Pager::offset())->limit(Pager::limit())
            ->orderBy('id desc')
            ->asArray()->all();
        return $this->json($data);
    }
    
    /**
     * 作品信息详情
     * @return mixed
     */
    public function actionDesign()
    {
        $design = null;
        $designId = $this->request->get('id');
        if($designId && ( ! $design = Design::canEdit($designId, ['designer_id' => $this->user->id]))) {
            return $this->error('无效的招聘信息（Invalid Recruit）', 'designer/design-list');
        }
        if( ! $this->request->isPost) {
            return $this->render('design', [
                'design' => $design,
                'models' => Category::selector($this->params['designModelCategories']),
                'categories' => Category::selector($this->params['designCategories']),
            ]);
        }
        if( ! $design) {
            $design = new Design();
        }
        $params = $this->request->post();
        $checker = Checker::authentication(Design::flyer(), $params);
        if($checker['code'] != Checker::SuccessCode) {
            return $this->json('Invalid.Param', $checker['message']);
        }
        $design->loads($params);
        $design->designer_id = $this->user->id;
        // 开始上传图片
        $configurate = require Yii::getAlias('@common/config/uploader.php');
        // 上传缩略图
        $loader = (new Uploader($configurate['design']))->upload('thumb');
        if($loader['code'] == SuccessCode) {
            Util::trashUpload($design->thumb);
            $design->thumb = $loader['path'];
        }
        // 上传作品图片
        $loader = (new Uploader($configurate['design']))->upload('image');
        if($loader['code'] == SuccessCode) {
            Util::trashUpload($design->image);
            $design->image = $loader['path'];
        }
        if( ! $design->validate()) {
            // 参数异常，渲染错误页面
            return $this->json('Invalid.Param', $design->errors());
        }
        if($design->save()) {
            // 保存成功
            return $this->json(SuccessCode, '保存成功');
        }
        // 参数异常，渲染错误页面
        return $this->json('System.Error', '提交失败，请重试');
    }
}
